package com.ruoyi.fault.service.impl;

import java.util.List;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.SecurityUtils; // 导入SecurityUtils用于获取当前用户
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import com.ruoyi.common.utils.StringUtils;
import org.springframework.transaction.annotation.Transactional;
import com.ruoyi.fault.domain.FaultRepair;
import com.ruoyi.fault.domain.FaultAssign; // 可能需要，如果FaultReport中也直接引用FaultAssign
import com.ruoyi.fault.mapper.FaultReportMapper;
import com.ruoyi.fault.mapper.FaultRepairMapper; // <-- 新增：注入FaultRepairMapper
import com.ruoyi.fault.domain.FaultReport;
import com.ruoyi.fault.service.IFaultReportService;

/**
 * 故障报修Service业务层处理
 *
 * @author silence
 * @date 2025-07-21
 */
@Service
public class FaultReportServiceImpl implements IFaultReportService
{
    @Autowired
    private FaultReportMapper faultReportMapper;

    @Autowired // <-- 新增：注入FaultRepairMapper
    private FaultRepairMapper faultRepairMapper;

    /**
     * 查询故障报修
     *
     * @param id 故障报修主键
     * @return 故障报修
     */
    @Override
    public FaultReport selectFaultReportById(Long id)
    {
        return faultReportMapper.selectFaultReportById(id);
    }

    /**
     * 查询故障报修列表
     *
     * @param faultReport 故障报修
     * @return 故障报修
     */
    @Override
    public List<FaultReport> selectFaultReportList(FaultReport faultReport)
    {
        return faultReportMapper.selectFaultReportList(faultReport);
    }

    /**
     * 新增故障报修
     *
     * @param faultReport 故障报修
     * @return 结果
     */
    @Transactional
    @Override
    public int insertFaultReport(FaultReport faultReport)
    {
        faultReport.setCreateTime(DateUtils.getNowDate());
        faultReport.setCreateBy(SecurityUtils.getUsername()); // 设置主表创建人
        faultReport.setUpdateTime(DateUtils.getNowDate()); // 首次创建，更新时间也设置为当前
        faultReport.setUpdateBy(SecurityUtils.getUsername()); // 首次创建，更新人也设置为当前

        int rows = faultReportMapper.insertFaultReport(faultReport);
        insertFaultRepair(faultReport); // 内部会处理FaultRepair的 create/update 时间和人
        return rows;
    }

    /**
     * 修改故障报修
     *
     * @param faultReport 故障报修
     * @return 结果
     */
    @Transactional
    @Override
    public int updateFaultReport(FaultReport faultReport)
    {
        faultReport.setUpdateTime(DateUtils.getNowDate());
        faultReport.setUpdateBy(SecurityUtils.getUsername()); // 设置主表更新人

        Long reportId = faultReport.getId();

        // --- 级联删除子表和孙子表数据，再重新插入 ---

        // 1. 获取所有与当前 fault_report 关联的 fault_repair 的 ID
        List<Long> repairIdsToCascade = faultReportMapper.selectRepairIdsByReportId(reportId);

        // 2. 如果存在关联的 repair_id，则先删除 fault_assign 表中关联的记录
        if (repairIdsToCascade != null && !repairIdsToCascade.isEmpty()) {
            // 注意：这里假设 faultRepairMapper 中有 deleteFaultAssignByRepairIds 方法
            faultRepairMapper.deleteFaultAssignByRepairIds(repairIdsToCascade.toArray(new Long[0]));
        }

        // 3. 删除 fault_repair 表中关联的记录 (report_id 外键)
        faultReportMapper.deleteFaultRepairByReportId(reportId);

        // 4. 重新新增 fault_repair 记录 (由 insertFaultRepair 辅助方法处理)
        insertFaultRepair(faultReport); // 内部会处理FaultRepair的 create/update 时间和人

        // 5. 更新 fault_report 自身记录
        return faultReportMapper.updateFaultReport(faultReport);
    }

    /**
     * 批量删除故障报修
     *
     * @param ids 需要删除的故障报修主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteFaultReportByIds(Long[] ids)
    {
        // --- 级联删除孙子表、子表数据 ---

        // 1. 获取所有与这些故障报告关联的 fault_repair 的 ID (孙子表的父ID)
        List<Long> repairIdsToCascade = faultReportMapper.selectRepairIdsByReportIds(ids);

        // 2. 如果存在关联的 repair_id，则先删除 fault_assign 表中关联的记录
        if (repairIdsToCascade != null && !repairIdsToCascade.isEmpty()) {
            // 注意：这里假设 faultRepairMapper 中有 deleteFaultAssignByRepairIds 方法
            faultRepairMapper.deleteFaultAssignByRepairIds(repairIdsToCascade.toArray(new Long[0]));
        }

        // 3. 删除 fault_repair 表中与这些故障报告关联的所有记录 (report_id 外键)
        faultReportMapper.deleteFaultRepairByReportIds(ids);

        // 4. 删除 fault_report 自身记录
        return faultReportMapper.deleteFaultReportByIds(ids);
    }

    /**
     * 删除故障报修信息
     *
     * @param id 故障报修主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteFaultReportById(Long id)
    {
        // --- 级联删除孙子表、子表数据 ---

        // 1. 获取所有与当前 fault_report 关联的 fault_repair 的 ID
        List<Long> repairIdsToCascade = faultReportMapper.selectRepairIdsByReportId(id);

        // 2. 如果存在关联的 repair_id，则先删除 fault_assign 表中关联的记录
        if (repairIdsToCascade != null && !repairIdsToCascade.isEmpty()) {
            // 注意：这里假设 faultRepairMapper 中有 deleteFaultAssignByRepairId 方法
            // 如果只有批量方法，也可以用：faultRepairMapper.deleteFaultAssignByRepairIds(new Long[]{id});
            faultRepairMapper.deleteFaultAssignByRepairIds(repairIdsToCascade.toArray(new Long[0]));
        }

        // 3. 删除 fault_repair 表中关联的记录 (report_id 外键)
        faultReportMapper.deleteFaultRepairByReportId(id);

        // 4. 删除 fault_report 自身记录
        return faultReportMapper.deleteFaultReportById(id);
    }

    /**
     * 新增故障处理信息 (辅助方法，由 insertFaultReport 和 updateFaultReport 调用)
     *
     * @param faultReport 故障报修对象，包含关联的 faultRepairList
     */
    public void insertFaultRepair(FaultReport faultReport)
    {
        List<FaultRepair> faultRepairList = faultReport.getFaultRepairList();
        Long reportId = faultReport.getId(); // faultReport 的 ID 在 insertFaultReport 后已经有了，或在 updateFaultReport 时已有

        if (StringUtils.isNotNull(faultRepairList))
        {
            List<FaultRepair> listToInsert = new ArrayList<>();
            for (FaultRepair faultRepair : faultRepairList)
            {
                faultRepair.setReportId(reportId); // 设置外键关联

                // *** 关键修正点1：为每个 FaultRepair 设置 createTime 和 createBy ***
                faultRepair.setCreateTime(DateUtils.getNowDate());
                faultRepair.setCreateBy(SecurityUtils.getUsername());
                // *** 关键修正点2：为每个 FaultRepair 设置 updateTime 和 updateBy ***
                // 在新增子表记录时，更新时间和更新人通常与创建时间创建人相同
                faultRepair.setUpdateTime(DateUtils.getNowDate());
                faultRepair.setUpdateBy(SecurityUtils.getUsername());

                listToInsert.add(faultRepair);
            }
            if (!listToInsert.isEmpty()) // 避免空列表调用 batch
            {
                faultReportMapper.batchFaultRepair(listToInsert);
            }
        }
    }
}
